package cn.edu.hitsz.compiler.parser;

import cn.edu.hitsz.compiler.lexer.Token;
import cn.edu.hitsz.compiler.parser.table.*;
import cn.edu.hitsz.compiler.parser.table.symbol.SenSymbol;
import cn.edu.hitsz.compiler.symtab.SymbolTable;

import java.util.Stack;

// TODO: 实验三: 实现语义分析
public class SemanticAnalyzer implements ActionObserver {
    private SymbolTable symbolTable;
    private Stack<SenSymbol> semanteme = new Stack<>();

    @Override
    public void whenAccept(Status currentStatus) {
        // TODO: 该过程在遇到 Accept 时要采取的代码动作
        //throw new NotImplementedException();
        //无需操作！
    }

    @Override
    public void whenReduce(Status currentStatus, Production production) {
        // TODO: 该过程在遇到 reduce production 时要采取的代码动作
        //throw new NotImplementedException();
        switch (production.index()){
            case 5 -> {
                SenSymbol temp = new SenSymbol(production.head());
                temp.setSourceCodeType(semanteme.peek().getSourceCodeType());
                semanteme.pop();
                semanteme.push(temp);
            }
            case 4 -> {
                SenSymbol temp = semanteme.pop();
                SenSymbol def = semanteme.pop();
                if(symbolTable.has(temp.getToken().getText())){
                    temp.setSourceCodeType(def.getSourceCodeType());
                    symbolTable.get(temp.getToken().getText()).setType(temp.getSourceCodeType());
                }
            }
        }

    }

    @Override
    public void whenShift(Status currentStatus, Token currentToken) {
        // TODO: 该过程在遇到 shift 时要采取的代码动作
        //throw new NotImplementedException();
        SenSymbol temp = new SenSymbol(currentToken);
        semanteme.add(temp);
    }

    @Override
    public void setSymbolTable(SymbolTable table) {
        // TODO: 设计你可能需要的符号表存储结构
        // 如果需要使用符号表的话, 可以将它或者它的一部分信息存起来, 比如使用一个成员变量存储
        //throw new NotImplementedException();
        this.symbolTable = table;
    }
}

